#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h> /* ioctl */
#include <time.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <errno.h>
#include "public.h"

#define POWER_OFF_TIMER_SEC     5
#define SIG_POWER_OFF    SIGRTMIN+16

static struct key_info * info;

static int xy_send_poweroff(void)
{
  char cmd_result[32] = {0};
  int pid = 0;
  int ret = -1;
  
  xy_popen_with_result("ps -e | grep 'led-daemon' |grep -v grep  | awk '{print $1}'", cmd_result, 32);

  if(strlen(cmd_result) > 0) {
    pid = atoi(cmd_result);

    ac_traces(MSG_LEVEL_INFO, "xy_send_poweroff pid:%d", pid);

    if(pid > 0) {
      ret = kill(pid, SIG_POWER_OFF);
      ac_traces(MSG_LEVEL_INFO, "send poweroff signal ret:%d errno:%d", ret, errno);
    } else {
      ac_traces(MSG_LEVEL_INFO, "not send signal");
    }
  }
  
  return true;
}

int xy_key_open(void)
{
  int dev = -1;

  dev = open(KEYS, O_RDONLY);
  if (dev <= 0) {
    ac_traces(MSG_LEVEL_ERROR, "open key device fail:%d\n", dev);
    return false;
  }  

  info = (struct key_info *) malloc (sizeof(struct key_info));
  if (!info) {
    ac_traces(MSG_LEVEL_ERROR, "malloc fail.");
    return false;
  }

  info->dev = dev;

  return true;
}

static int xy_reboot(void)
{
  if (execl("/sbin/reboot", "reboot", "executed by execl", NULL) < 0) {
    ac_traces(MSG_LEVEL_INFO, "error on execl");
    return false;
  }

  ac_traces(MSG_LEVEL_INFO, "system reboot");
  return 0;
}

static int xy_4g_network_reboot(void)
{
  xy_popen("killall quectel-CM");
  sleep(1);
  xy_popen("quectel-CM -s ctnet &");

  return true;
}

static int xy_sync(void)
{
  xy_popen("sync");

  return true;
}

static int xy_poweroff(void)
{
  ac_traces(MSG_LEVEL_INFO, "send poweroff signal");
  xy_send_poweroff();
  
  sleep(1);
  
  ac_traces(MSG_LEVEL_INFO, "system poweroff");
  xy_popen("poweroff");

  return true;
}

void * xy_key_press_thread(void)
{
  int key_status_2 = -1;
  int key_status_5 = -1;
  struct timespec key5_begin_tp,key5_cur_tp;
  int  key5_pressed = 0;

  while (true) {
    key_status_2 = -1;
    if (0 == ioctl(info->dev, GET_KEY_J20_STATUS, &key_status_2))
      ac_traces(MSG_LEVEL_MAX, "key2 status is %s\n", key_status_2 == 1?"released":"pressed");
    else
      ac_traces(MSG_LEVEL_WARNING, "get key j20 status fail.");

    key_status_5 = -1;
    if (0 == ioctl(info->dev, GET_KEY_J50_STATUS, &key_status_5))
      ac_traces(MSG_LEVEL_MAX, "key5 status is %s\n", key_status_5 == 1?"released":"pressed");
    else
      ac_traces(MSG_LEVEL_WARNING, "get key j50 status fail.");

    if (key_status_2 == PRESSED && key_status_5 == PRESSED) {
      ac_traces(MSG_LEVEL_INFO, "both key event");
      xy_reboot();
    }

    if (key_status_2 == PRESSED) {
      ac_traces(MSG_LEVEL_INFO, "4g light event");
      xy_4g_network_reboot();
    }

    if (key_status_5 == PRESSED) {
      ac_traces(MSG_LEVEL_INFO, "usb light event");
      
      if(key5_pressed == 0) {
        clock_gettime(CLOCK_REALTIME,&key5_begin_tp);
        key5_pressed = 1;
      } else {
        clock_gettime(CLOCK_REALTIME,&key5_cur_tp);
        if((key5_cur_tp.tv_sec - key5_begin_tp.tv_sec) >= POWER_OFF_TIMER_SEC) {
          ac_traces(MSG_LEVEL_INFO, "usb light event");
					
          key5_pressed = 0;
          xy_sync();
          sleep(2);
          xy_poweroff();
        }
      }
      
      //xy_sync();
      //sleep(3);
      //xy_u_eject();
    }
    else
    {
      key5_pressed = 0;
    }
 
    usleep(1000);
  }
}

int xy_key_press_thread_run(void)
{
  pthread_attr_t attr;
  pthread_t key_id = 0;
  int ret = 0;
  void * ptr;

  pthread_attr_init(&attr);

  if (0 != (ret = pthread_create(&key_id, &attr, (void * (*)(void *))xy_key_press_thread, NULL))) {
    ac_traces(MSG_LEVEL_ERROR, "create key press thread fail. error=%d", ret);
    return false;
  }

  ac_traces(MSG_LEVEL_INFO, "key-press thread create successfuly!");
  pthread_join(key_id, &ptr);

  return true;
}
